package drds.plus.repository.mysql.function.all;

import drds.plus.common.jdbc.SetParameterMethodAndArgs;
import drds.plus.executor.function.scalar.filter.Filter;
import drds.plus.repository.mysql.execute_plan_to_sql.ExecutePlanVisitor;
import drds.plus.repository.mysql.function.FunctionStringConstructor;
import drds.plus.sql_process.abstract_syntax_tree.execute_plan.ExecutePlan;
import drds.plus.sql_process.abstract_syntax_tree.expression.item.function.Function;
import drds.plus.sql_process.abstract_syntax_tree.expression.item.function.Operation;
import drds.plus.sql_process.type.Type;

import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

public class EqualAll implements FunctionStringConstructor {

    public String constructColumnNameForFunction(ExecutePlan query, boolean bindVal, AtomicInteger bindValSequence, Map<Integer, SetParameterMethodAndArgs> paramMap, Function function, ExecutePlanVisitor parentVisitor) {
        StringBuilder sb = new StringBuilder();

        Object right = function.getArgList().get(1);

        if (right instanceof List) {
            boolean isAllEqual = true;
            List rightList = (List) right;

            if (rightList.size() == 0) {
                sb.append(" (false) ");
                return sb.toString();
            }
            Type type = ((Filter) function.getExtraFunction()).getArgType();
            for (int i = 0; i < rightList.size() - 1; i++) {
                if (type.compare(rightList.get(i), rightList.get(i + 1)) != 0) {
                    isAllEqual = false;
                    break;
                }
            }

            if (isAllEqual) {
                sb.append(parentVisitor.getNewExecutePlanVisitor(function.getArgList().get(0)).getString());
                sb.append(" = ");
                sb.append(parentVisitor.getNewExecutePlanVisitor(rightList.get(0)).getString());
            } else {
                sb.append(" (false) ");
            }

        } else {

            sb.append(parentVisitor.getNewExecutePlanVisitor(function.getArgList().get(0)).getString());

            // 右边没进行计算，还是个子查询，理论上不会发生
            sb.append(" = all (");
            sb.append(parentVisitor.getNewExecutePlanVisitor(function.getArgList().get(1)).getString());
            sb.append(")");
        }

        return sb.toString();

    }

    public String[] getFunctionNames() {
        return new String[]{Operation.equal_all.getOperationString()};
    }
}
